#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QSqlQueryModel>
#include <QInputDialog>
#include <QPrinter>
#include <QTextDocument>
#include <QDesktopServices>
#include "newbilldialog.h"
#include "paytypedialog.h"
#include "newpaydialog.h"
#include "aboutdialog.h"

#define PDF_TEMP ".PigBills/temp.pdf"

void MainWindow::refreshPayments() {
    QString sql = "select l.bill_date 'Bill Date', t.name 'Type', printf('%.2f',l.amount) 'Amount', l.description 'Description' from pig_bill_headers h, pig_bill_pays l, pig_pay_types t where l.bill_header_id=h.bill_header_id and l.pay_type_id=t.pay_type_id and h.bill_header_id=";
    sql += ui->comboBox->currentData().toString();
    sql += " order by l.bill_date asc";
    model->setQuery(sql);
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}

void MainWindow::refreshBillAmount() {
    QSqlQuery q;
    q.prepare("select amount,budget from pig_bill_headers where bill_header_id=:bill_header_id");
    q.bindValue(":bill_header_id", ui->comboBox->currentData());
    q.exec();
    if (q.next()) {
        double amount = q.value(0).toDouble();
        double budget = q.value(1).toDouble();
        QString str;
        if (amount < budget) {
            str = "<font color='green'>";
        }
        else {
            str = "<font color='red'>";
        }
        str += QString::number(amount,'d',2);
        str += " / ";
        str += QString::number(budget,'d',2);
        str += "</font>";
        billStatus->setText(str);
        int pbudget=budget*100;
        int pamount=amount*100;
        int remain=pbudget-pamount;
        if(remain<0){
            remain=0;
        }
        if(remain>pbudget){
            remain=pbudget;
        }
        ui->progressBar->setRange(0,pbudget);
        ui->progressBar->setValue(remain);
    }
}

void MainWindow::refreshBills() {
    ui->comboBox->clear();
    QSqlQuery q;
    q.prepare("select name, bill_header_id from pig_bill_headers order by last_modified_date desc");
    q.exec();
    while (q.next()) {
        ui->comboBox->addItem(q.value(0).toString(), q.value(1).toInt());
    }
    if (ui->comboBox->count()) {
        if (currentBill == -1) {
            ui->comboBox->setCurrentIndex(0);
            currentBill = ui->comboBox->currentIndex();
        }
        else
        {
            ui->comboBox->setCurrentIndex(currentBill);
        }
    }
    q.clear();
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    currentBill = -1;
    billStatus = new QLabel("Ready");
    ui->statusBar->addWidget(billStatus);
    //Init Bill List;
    refreshBills();
    //Init Status;
    refreshBillAmount();
    //Init Payments;
    model = new QSqlQueryModel();
    ui->tableView->setModel(model);
    //ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    refreshPayments();
}

void MainWindow::resizeEvent(QResizeEvent *e)
{
    QMainWindow::resizeEvent(e);
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}

MainWindow::~MainWindow()
{
    delete model;
    delete ui;
}

void MainWindow::on_comboBox_activated(int index)
{
    //QMessageBox::warning(this, "Show", ui->comboBox->itemData(index).toString());
    currentBill = index;
    refreshBillAmount();
    refreshPayments();
}

void MainWindow::on_actionNew_Bill_triggered()
{
    NewBillDialog nbd;
    nbd.exec();
    if (nbd.created) {
        currentBill = 0;
    }
    refreshBills();
    refreshBillAmount();
    refreshPayments();
}

void MainWindow::on_actionPayment_Types_triggered()
{
    PayTypeDialog ptd;
    ptd.exec();
}

void MainWindow::on_actionNew_Payment_triggered()
{
    if (currentBill == -1) {
        QMessageBox::warning(this, tr("Pig Bills"), tr("You need a bill before add payments!"));
        return;
    }
    NewPayDialog npd;
    npd.setBill(currentBill);
    npd.exec();
    refreshBillAmount();
    refreshPayments();
}

void MainWindow::on_actionExit_triggered()
{
    qApp->exit(0);
}

void MainWindow::on_actionSet_Password_triggered()
{
    bool isOK;
    QSqlQuery q;
    QString raw = QInputDialog::getText(this, tr("Pig Bills"), tr("Password(Clear current password if enter nothing)"), QLineEdit::Password, NULL, &isOK);
    if (isOK) {
        //Clear password first;
        q.prepare("delete from pig_config where name='PASSWORD'");
        q.exec();
        if (raw.isEmpty()) {
            return;
        }
        //Setup new password;
        QByteArray rawPassword = QCryptographicHash::hash(raw.toUtf8(), QCryptographicHash::Md5);
        QString password = QString(rawPassword.toHex());
        q.prepare("insert into pig_config (name,value,last_modified_date) values ('PASSWORD',:password,datetime('now'))");
        q.bindValue(":password", password);
        q.exec();
    }
}

void MainWindow::on_actionAbout_triggered()
{
    AboutDialog ad;
    ad.exec();
}

void MainWindow::on_actionSet_Budget_triggered()
{
    if (currentBill == -1) {
        QMessageBox::warning(this, tr("Pig Bills"), tr("You need a bill before add payments!"));
        return;
    }
    bool isOK;
    double oldBudget=0;
    QSqlQuery q;
    q.prepare("select budget from pig_bill_headers where bill_header_id=:bill_header_id");
    q.bindValue(":bill_header_id", ui->comboBox->currentData().toInt());
    q.exec();
    if (q.next()) {
        oldBudget = q.value(0).toDouble();
    }
    double budget = QInputDialog::getDouble(this, "Pig Bills", "Set budget", oldBudget, 0, 9999999.99, 2, &isOK);
    if (isOK) {
        q.prepare("update pig_bill_headers set budget=:budget, last_modified_date=datetime('now') where bill_header_id=:bill_header_id");
        q.bindValue(":budget", budget);
        q.bindValue(":bill_header_id", ui->comboBox->currentData().toInt());
        q.exec();
    }
    refreshBillAmount();
}

void MainWindow::on_actionCurrent_Bill_triggered()
{
    if (currentBill == -1) {
        QMessageBox::warning(this, tr("Pig Bills"), tr("You need a bill before add payments!"));
        return;
    }
    QSqlQuery q;
    q.prepare("select name, amount, budget, datetime('now') from pig_bill_headers where bill_header_id=:bill_header_id");
    q.bindValue(":bill_header_id", ui->comboBox->currentData().toInt());
    q.exec();
    QString name,amount,budget,generate_date;
    if(q.next()){
        name=q.value(0).toString();
        amount=q.value(1).toString();
        budget=q.value(2).toString();
        generate_date=q.value(3).toString();
        q.clear();
    }
    QPrinter printer;
    printer.setOutputFormat(QPrinter::PdfFormat);
    QString temp=QDir::homePath();
    temp+="/";
    temp+=PDF_TEMP;
    printer.setOutputFileName(temp);
    QTextDocument doc;
    QFile fTemplate(":/template/en/report_currentBill");
    fTemplate.open(QIODevice::ReadOnly);
    QString str=fTemplate.readAll();
    str.replace("<!-- [% Title %] -->",name);
    str.replace("<!-- [% Amount %] -->",amount);
    str.replace("<!-- [% Generate Date %] -->",generate_date);
    str.replace("<!-- [% Budget %] -->",budget);
    int lines=0;
    QString sql = "select l.bill_date 'Bill Date', t.name 'Type', printf('%.2f',l.amount) 'Amount', l.description 'Description' from pig_bill_headers h, pig_bill_pays l, pig_pay_types t where l.bill_header_id=h.bill_header_id and l.pay_type_id=t.pay_type_id and h.bill_header_id=";
    sql += ui->comboBox->currentData().toString();
    sql += " order by l.bill_date asc";
    q.prepare(sql);
    q.exec();
    QString line_data="";
    while(q.next()){
        lines+=1;
        line_data+="<tr>";
        line_data+="<td>";
        line_data+=q.value(0).toString();
        line_data+="</td>";
        line_data+="<td>";
        line_data+=q.value(1).toString();
        line_data+="</td>";
        line_data+="<td>";
        line_data+=q.value(2).toString();
        line_data+="</td>";
        line_data+="<td>";
        line_data+=q.value(3).toString();
        line_data+="</td>";
        line_data+="</tr>";
    }
    q.clear();
    str.replace("<!-- [% Line Data %] -->",line_data);
    str.replace("<!-- [% Line of Payments %] -->",QString::number(lines));
    doc.setHtml(str);
    fTemplate.close();
    doc.print(&printer);
    if(!QDesktopServices::openUrl(QUrl(temp,QUrl::TolerantMode))){
        QMessageBox::warning(this, tr("Pig Bills"), tr("It seems that you do not have a PDF reader installed!"));
    }
}
